#include "head.h"
//客户端gets处理逻辑
//将下载的内容存在本地i

// 保存接收的文件偏移量到文件中
void save_received_offset_two(const char *file_name, off_t offset) {
    char offset_file[256];

    snprintf(offset_file, sizeof(offset_file), "%s.offset",file_name);
    FILE *fp = fopen(offset_file, "w");
    printf("file = %s\n", offset_file);
    if (fp) {
        printf("close!\n");
        //偏移量写入文件
        fprintf(fp, "%ld\n", offset);
        fclose(fp);
    }
}

// 从文件中读取已接收的文件偏移量
off_t get_received_offset_two(const char *file_name) {
    char offset_file[256];
    //以  “文件完整所在路径＋offset”  作为存储偏移量数据的文件的文件名
    //用offset_file记录这个文件名
    snprintf(offset_file, sizeof(offset_file), "%s.offset",file_name);
    FILE *fp = fopen(offset_file, "r");
    off_t offset = 0;//初始化偏移量为零
    if (fp) {
        //从文件描述符fp的文件中，读取偏移量到offset
        fscanf(fp, "%ld", &offset);
        fclose(fp);
    }
    return offset;
}

bool my_gets(sendMsg msg,client_status clients,int net_fd)
{
    printf("my_gets进入处理.\n");
    //1.发mode进入相应的函数
    msg.mode=4;
    send(net_fd,&msg,sizeof(msg),MSG_NOSIGNAL);

    char *next;
    char *last_token;
    char *token=strtok_r(clients.path_last,"/",&next);
    while(token!=NULL){
        last_token=token;
        token=strtok_r(NULL,"/",&next);
    }

    //2.发文件名文件长度
    char file_name[1000];
    strcpy(file_name,last_token);

    int file_name_len=strlen(last_token);
    send(net_fd,&file_name_len,sizeof(int),MSG_NOSIGNAL);
    send(net_fd,file_name,file_name_len,MSG_NOSIGNAL);
    
    //3.获取当前的下载文件的偏移量,再发给服务器
    int offset=get_received_offset_two(file_name);
    send(net_fd,&offset,sizeof(int),MSG_NOSIGNAL);

    // 接收文件大小
    off_t file_size;
    int ret=recv(net_fd, &file_size, sizeof(off_t), MSG_WAITALL);
    ERROR_CHECK(ret,-1,"ret_file_size");
    printf("file_size: %ld %d\n", file_size,ret);

    //开文件
    int file_fd = open(file_name, O_RDWR|O_CREAT, 0666);
    ERROR_CHECK(file_fd,-1,"file_fd");
    // 文件调整需要的大小
    int ret_f=ftruncate(file_fd, file_size);
    ERROR_CHECK(ret_f,-1,"ret_f");

    //开启mmap映射
    char *p = (char *)mmap(NULL, file_size, PROT_READ|PROT_WRITE, MAP_SHARED, file_fd, 0);
      if (p == MAP_FAILED) { // 错误处理
        perror("mmap");
        close(file_fd);
        return false;
    }


    //接收文件
    while (offset < file_size) {
        //已接收文件大小<文件大小时循环读取
        int ret_recv1 = recv(net_fd, p + offset, file_size - offset, 0);
        //下面是读取的错误处理
        if (ret_recv1 <= 0) {
            if (errno == EINTR || errno == EAGAIN) {
                //发生错误断开
                continue; // 如果发生了中断或资源临时不可用，继续接收
            } else {
                //客户端退出断开
                //关闭资源
                perror("recv file data");
                munmap(p, file_size);
                close(file_fd);
                //保存偏移量
                save_received_offset_two(file_name,offset);
                return false;
            }

        }

        printf("recv_bytes:%d\n",ret_recv1);
        offset += ret_recv1;
        save_received_offset_two(file_name, offset);
        sleep(1);
    }
    munmap(p, file_size);

    close(file_fd);
    close(net_fd);
    //传完再存一次偏移量，方便对比文件传输状态
    save_received_offset_two(file_name, offset);
    return 0;


}
